/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ai;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.sql.*;
import java.util.LinkedList;

/**
 *
 * @author root
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        QueryForm lQF = null;
        LexiconParser lLex = null;
        KnowledgeBase lKB = null;
        ChartParser lCP = null;
        KeyWordAI key = null;

        try {
            lLex = new LexiconParser();
            lKB = lLex.load("src/ai/rules.txt");
            lCP = new ChartParser(lKB);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParseException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        Jdbc j = null;
        Connection conn = null;
        try {
            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            String url = "jdbc:oracle:thin:@tycho.ita.chalmers.se:1521/kingu.ita.chalmers.se";
            String userName = "TDA357_029"; // Your username goes here!
            String password = "B5TR5s"; // Your password goes here!
            conn = DriverManager.getConnection(url, userName, password);

            lQF = new QueryForm(conn);

            key = new KeyWordAI(lQF, conn);
            j = new Jdbc(lQF);
        } catch (SQLException e) {
            System.err.println(e);
            System.exit(2);
        }

//        j.checkAndExcIngrediens(conn);
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("What can I do for you?");
        System.out.flush();
        //System.out.print("> ");
        String lUserInput = input.readLine();

        while (!(lUserInput.equals("no"))) {
            String lQuestion = getRandomQuestion();

            // lFoodTalk will be true if the user said something regarding
            // food.
            boolean lFoodTalk = parseUsrInput(lUserInput, lLex, lKB, lCP, lQF, key);
            if (lFoodTalk == true && lQF.getFinalMeals().size() > 0) {
                String lReply = "\nI found " + lQF.getFinalMeals().size();

                if (lQF.getFinalMeals().size() == 1) {
                    lReply += " meal";
                } else {
                    lReply += " meals";
                }

                if (!lQF.getIncMeal().isEmpty()) {
                    lReply += " that you requested";
                } else {
                    if (!lQF.getIncIngrediens().isEmpty()) {
                        lReply += " with";
                    }
                    LinkedList<String> lIngr = lQF.getIncIngrediens();
                    for (String s : lIngr) {
                        lReply += " " + s;
                        if (!s.equals(lIngr.getLast()) && lIngr.size() >= 2) {
                            if (!s.equals(lIngr.get(lIngr.size() - 2))) {
                                lReply += ",";
                            } else {
                                lReply += " and";
                            }
                        }
                    }

                    if (lQF.getExcIngrediens().isEmpty() == false) {
                        if (!lQF.getIncIngrediens().isEmpty()) {
                            lReply += " but";
                        }
                        lReply += " with no";
                    }

                    lIngr = lQF.getExcIngrediens();
                    for (String s : lIngr) {
                        lReply += " " + s;
                        if (!s.equals(lIngr.getLast()) && lIngr.size() >= 2) {
                            if (!s.equals(lIngr.get(lIngr.size() - 2))) {
                                lReply += ",";
                            } else {
                                lReply += " or";
                            }
                        }
                    }
                }
                System.out.print(lReply + ".\n\n");
                for (int i = 0; i < lQF.getFinalMeals().size(); i++) {
                    System.out.println(lQF.getFinalMeals().get(i));
                }
            } else if (lFoodTalk) {
                System.out.println("I'm sorry, but I didn't find any recipes matching your request.");
            } else {
                lQuestion = "From my very narrow point of view, that didn't have anything to do with food or cooking.\nCan we focus on finding a recipe in my database?\n";
            }

            boolean lDone = false;
            while (!lDone) {
                System.out.println(lQuestion);
                lUserInput = input.readLine();
                System.out.println(""); // New line.
                if (lUserInput.equals("yes")) {
                    lQuestion = "Great! How can I serve you?\n";
                } else {
                    lDone = true;
                }
            }
        }

        System.out.println("Ok! Goodbye!");

        j.finalMeal(conn);
    }

    static private String getRandomQuestion() {
        int lQuestion = (int) (Math.random() * 9);
        switch (lQuestion) {
            case 0:
                return "\nIs there anything else you whould like?\n";
            case 1:
                return "\nWould you like to narrow your request?\n";
            case 2:
                return "\nAnything else?\n";
            case 3:
                return "\nSomething else?\n";
            case 4:
                return "\nAnything else you would like?\n";
            case 5:
                return "\nSomething else you would like?\n";
            case 6:
                return "\nCan I help you with something more?\n";
            case 7:
                return "\nWould you like to add or remove something?\n";
            case 8:
                return "\nDo you want to change anything?\n";
            case 9:
                return "\nAny other requests?\n";
        }
        return null;
    }

    public static boolean parseUsrInput(String pUserInput, LexiconParser pLex, KnowledgeBase pKB, ChartParser pCP, QueryForm pQF, KeyWordAI key) {
        String lUserInput[] = pUserInput.split("[.,!?]");
        boolean lOk = false;
        for (int i = 0; i < lUserInput.length; i++) {
            lUserInput[i] = lUserInput[i].trim();
            try {
                ParseNode lParseTree = pCP.parse(lUserInput[i]);
                boolean lParseOk = false;
                if (lParseTree != null) {
                    //System.out.println(lParseTree);
                    lParseOk = lParseTree.executeSemantics(pKB, pQF);
                }

                if (!lParseOk && !lOk) {
                    System.out.println("The phrase \"" + lUserInput[i] + "\" seems strange to me...\nI don't understand it, so I will look for keywords.");
                    lParseOk = key.inputHandler(lUserInput[i]);
                }

                if (lParseOk) {
                    lOk = true;
                }

            } catch (ParseException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return lOk;
    }
}
